using Game.Terrain.Terrain;
using UnityEngine;
using UnityEngine.Tilemaps;

public class TerrainComponent : MonoBehaviour, IGameComponent
{
    private static readonly int MainTex = Shader.PropertyToID("_MainTex");

    [SerializeField] private TileBase _grassTile;
    [SerializeField] private TileBase _waterTile;
    [SerializeField] private Tilemap _terrainTilemap;
    [SerializeField] private Grid _terrainGrid;
    [SerializeField] Vector2Int _mapSize = new Vector2Int(256, 256);
    [SerializeField] MeshFilter meshFilter;
    [SerializeField] MeshRenderer meshRenderer;
    [SerializeField] Texture2D terrainTexture;

    [SerializeField] [Range(1, 40)] private float scale = 1;

    [SerializeField] private float offsetX = 1;

    [SerializeField] private float offsetY = 1;
    [SerializeField] [Range(1, 9)] private float value;

    public void Init()
    {
        // GenericTerrain();
    }

    public void SetTerrainSize()
    {
        Mesh mesh = meshFilter.sharedMesh;
        mesh = new Mesh();
        Bounds bounds = new Bounds(Vector3.zero,new Vector3(_mapSize.x,_mapSize.y,0) );
        mesh.vertices = new Vector3[]
        {
            bounds.min,
            new Vector3(bounds.min.x, bounds.max.y, 0),
            bounds.max,
            new Vector3(bounds.max.x, bounds.min.y, 0)
        };
        mesh.triangles = new int[] { 0, 1, 2, 0, 2, 3 };
        mesh.RecalculateNormals();
        mesh.uv = new Vector2[]
        {
            new Vector2(0, 0),
            new Vector2(0, 1),
            new Vector2(1, 1),
            new Vector2(1, 0)
        };
        meshFilter.sharedMesh = mesh;
        Material material = new Material(Shader.Find("Mobile/Unlit (Supports Lightmap)"));
        // 设置材质的缩放和偏移
        material.SetTextureScale(MainTex, _mapSize);
        material.SetTexture(MainTex, terrainTexture);
        //material.SetTextureOffset("_MainTex", offset);
        meshRenderer.sharedMaterial = material;
    }

    private void GenericTerrain()
    {
        var positions = new Vector3Int[_mapSize.x * _mapSize.y];
        var tiles = new TileBase[positions.Length];

        for (int y = 0; y < _mapSize.y; y++)
        {
            for (int x = 0; x < _mapSize.x; x++)
            {
                int index = y * _mapSize.x + x;
                positions[index] = new Vector3Int(x, y, 0);
                tiles[index] = _grassTile;
            }
        }

        _terrainTilemap.SetTiles(positions, tiles);
    }

    public void GenericTerrainByPerling()
    {
        float time =Time.realtimeSinceStartup;
        var positions = GenerateHeightMap(_mapSize.x, _mapSize.y, scale, offsetX, offsetY);
        Debug.Log($"生成地图耗时0:{Time.realtimeSinceStartup - time}");
        time = Time.realtimeSinceStartup;
        var tiles = new TileBase[positions.Length];
        
        
        for (int i = 0; i < positions.Length; i++)
        {
            tiles[i] = positions[i].z > value ? _grassTile : _waterTile;
            positions[i].z = 0;
        }
        Debug.Log($"生成地图耗时1:{Time.realtimeSinceStartup - time}");
        time = Time.realtimeSinceStartup;
        _terrainTilemap.SetTiles(positions, tiles);
        Debug.Log($"生成地图耗时2:{Time.realtimeSinceStartup - time}");
        
        
        Debug.Log( $" {_terrainTilemap.cellBounds}");
       
    }

    public void Clear()
    {
        _terrainTilemap.ClearAllTiles();
    }

    public Vector3Int[] GenerateHeightMap(int width, int height, float scale, float offsetX, float offsetY)
    {
        Vector3Int[] heightMap = new Vector3Int[width * height];
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                // 通过偏移和缩放参数控制噪声分布
                float xCoord = offsetX + x / (float)width * scale;
                float yCoord = offsetY + y / (float)height * scale;
                heightMap[width * y + x] = new Vector3Int(x, y, (int)(10 * Mathf.PerlinNoise(xCoord, yCoord)));
            }
        }

        return heightMap;
    }
    async void Start()
    {
        TerrainManager terrainManager = new TerrainManager();
        terrainManager.Init(_terrainTilemap, _mapSize.x, _mapSize.y);
        terrainManager.GenerateDecorativeBuildings();
    }
}